<div class="content-section introduction">
    <div class="feature-intro">
        <h1>CascadeSelect</h1>
        <p>CascadeSelect displays a nested structure of options.</p>
    </div>
    <app-demoActions github="cascadeselect" stackblitz="cascadeselect-demo"></app-demoActions>
</div>

<div class="content-section implementation">
    <div class="card">
        <h5>Basic</h5>
        <p-cascadeSelect [(ngModel)]="selectedCity1" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
            [optionGroupChildren]="['states', 'cities']" [style]="{'minWidth': '14rem'}" placeholder="Select a City"></p-cascadeSelect>

        <h5>Templating</h5>
        <p-cascadeSelect [(ngModel)]="selectedCity2" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
            [optionGroupChildren]="['states', 'cities']" [style]="{'minWidth': '14rem'}" placeholder="Select a City">
            <ng-template pTemplate="option" let-option>
                <div class="country-item">
                    <img *ngIf="option.states" src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + option.code.toLowerCase()"/>
                    <i class="pi pi-compass mr-2" *ngIf="option.cities"></i>
                    <i class="pi pi-map-marker mr-2" *ngIf="option.cname"></i>
                    <span>{{option.cname || option.name}}</span>
                </div>
            </ng-template>
        </p-cascadeSelect>
    </div>
</div>

<div class="content-section documentation">
    <p-tabView>
        <p-tabPanel header="Documentation">
            <h5>Import</h5>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;CascadeSelectModule&#125; from 'primeng/cascadeselect';
</app-code>
            <h5>Getting Started</h5>
            <p>CascadeSelect requires a value to bind and a collection of arbitrary objects with a nested hierarchy. <i>optionGroupLabel</i>
                is used for the text of a category and <i>optionGroupChildren</i> is to define the children of the category. Note that order of the <i>optionGroupChildren</i>
                matters and it should correspond to the data hierarchy.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-cascadeSelect [(ngModel)]="selectedCity1" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
    [optionGroupChildren]="['states', 'cities']" [style]="&#123;'minWidth': '14rem'&#125;"&gt;&lt;/p-cascadeSelect&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
countries: any[];

selectedCity1: any;

ngOnInit() &#123;
    this.countries = [
        &#123;
            name: 'Australia',
            code: 'AU',
            states: [
                &#123;
                    name: 'New South Wales',
                    cities: [
                        &#123;cname: 'Sydney', code: 'A-SY'&#125;,
                        &#123;cname: 'Newcastle', code: 'A-NE'&#125;,
                        &#123;cname: 'Wollongong', code: 'A-WO'&#125;
                    ]
                &#125;,
                &#123;
                    name: 'Queensland',
                    cities: [
                        &#123;cname: 'Brisbane', code: 'A-BR'&#125;,
                        &#123;cname: 'Townsville', code: 'A-TO'&#125;
                    ]
                &#125;,
                
            ]
        &#125;,
        &#123;
            name: 'Canada', 
            code: 'CA',
            states: [
                &#123;
                    name: 'Quebec',
                    cities: [
                        &#123;cname: 'Montreal', code: 'C-MO'&#125;,
                        &#123;cname: 'Quebec City', code: 'C-QU'&#125;
                    ]
                &#125;,
                &#123;
                    name: 'Ontario',
                    cities: [
                        &#123;cname: 'Ottawa', code: 'C-OT'&#125;,
                        &#123;cname: 'Toronto', code: 'C-TO'&#125;
                    ]
                &#125;,
                
            ]
        &#125;,
        &#123;
            name: 'United States',
            code: 'US',
            states: [
                &#123;
                    name: 'California',
                    cities: [
                        &#123;cname: 'Los Angeles', code: 'US-LA'&#125;,
                        &#123;cname: 'San Diego', code: 'US-SD'&#125;,
                        &#123;cname: 'San Francisco', code: 'US-SF'&#125;
                    ]
                &#125;,
                &#123;
                    name: 'Florida',
                    cities: [
                        &#123;cname: 'Jacksonville', code: 'US-JA'&#125;,
                        &#123;cname: 'Miami', code: 'US-MI'&#125;,
                        &#123;cname: 'Tampa', code: 'US-TA'&#125;,
                        &#123;cname: 'Orlando', code: 'US-OR'&#125;
                    ]
                &#125;,
                &#123;
                    name: 'Texas',
                    cities: [
                        &#123;cname: 'Austin', code: 'US-AU'&#125;,
                        &#123;cname: 'Dallas', code: 'US-DA'&#125;,
                        &#123;cname: 'Houston', code: 'US-HO'&#125;
                    ]
                &#125;
            ]
        &#125;
    ];
&#125;
</app-code>

            <h5>Templating</h5>
            <p>Content of an item can be customized with the <i>option</i> template.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-cascadeSelect [(ngModel)]="selectedCity2" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
    [optionGroupChildren]="['states', 'cities']" [style]="&#123;'minWidth': '14rem'&#125;" placeholder="Select a City"&gt;
    &lt;ng-template pTemplate="option" let-option&gt;
        &lt;div class="country-item"&gt;
            &lt;img *ngIf="option.states" src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + option.code.toLowerCase()"/&gt;
            &lt;i class="pi pi-compass mr-2" *ngIf="option.cities"&gt;&lt;/i&gt;
            &lt;i class="pi pi-map-marker mr-2" *ngIf="option.cname"&gt;&lt;/i&gt;
            &lt;span&gt;&#123;&#123;option.cname || option.name&#125;&#125;&lt;/span&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-cascadeSelect&gt;
</app-code>

            <h5>Properties</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Type</th>
                            <th>Default</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>options</td>
                            <td>array</td>
                            <td>null</td>
                            <td>An array of selectitems to display as the available options.</td>
                        </tr>
                        <tr>
                            <td>optionLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Property name or getter function to use as the label of an option.</td>
                        </tr>
                        <tr>
                            <td>optionValue</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Property name or getter function to use as the value of an option, defaults to the option itself when not defined.</td>
                        </tr>
                        <tr>
                            <td>optionGroupLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Property name or getter function to use as the label of an option group.</td>
                        </tr>
                        <tr>
                            <td>optionGroupChildren</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Property name or getter function to retrieve the items of a group.</td>
                        </tr>
                        <tr>
                            <td>placeholder</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Default text to display when no option is selected.</td>
                        </tr>
                        <tr>
                            <td>disabled</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the component should be disabled.</td>
                        </tr>
                        <tr>
                            <td>dataKey</td>
                            <td>string</td>
                            <td>null</td>
                            <td>A property to uniquely identify an option.</td>
                        </tr>
                        <tr>
                            <td>tabindex</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Index of the element in tabbing order.</td>
                        </tr>
                        <tr>
                            <td>inputId</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Identifier of the underlying input element.</td>
                        </tr>
                        <tr>
                            <td>ariaLabelledBy</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
                        </tr>
                        <tr>
                            <td>appendTo</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Id of the element or "body" for document where the overlay should be appended to.</td>
                        </tr>
                        <tr>
                            <td>style</td>
                            <td>object</td>
                            <td>null</td>
                            <td>Inline style of the component.</td>
                        </tr>
                        <tr>
                            <td>styleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the component.</td>
                        </tr>
                        <tr>
                            <td>inputLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Label of the input for accessibility.</td>
                        </tr>
                        <tr>
                            <td>ariaLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines a string that labels the input for accessibility.</td>
                        </tr>
                        <tr>
                            <td>ariaLabelledBy</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Specifies one or more IDs in the DOM that labels the input field.</td>
                        </tr>
                        <tr>
                            <td>showClear</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When enabled, a clear icon is displayed to clear the value.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Events</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onChange</td>
                            <td>event.originalEvent: Original event <br />
                                event.value: Selected option value </td>
                            <td>Callback to invoke on value change.</td>
                        </tr>
                        <tr>
                            <td>onGroupChange</td>
                            <td>event.originalEvent: Original event <br />
                                event.value: Selected option group </td>
                            <td>Callback to invoke when a group changes.</td>
                        </tr>
                        <tr>
                            <td>onBeforeShow</td>
                            <td>-</td>
                            <td>Callback to invoke before the overlay is shown.</td>
                        </tr>
                        <tr>
                            <td>onBeforeHide</td>
                            <td>-</td>
                            <td>Callback to invoke before the overlay is hidden.</td>
                        </tr>
                        <tr>
                            <td>onShow</td>
                            <td>-</td>
                            <td>Callback to invoke when the overlay is shown.</td>
                        </tr>
                        <tr>
                            <td>onHide</td>
                            <td>-</td>
                            <td>Callback to invoke when the overlay is hidden.</td>
                        </tr>
                        <tr>
                            <td>onClear</td>
                            <td>-</td>
                            <td>Callback to invoke when input field is cleared.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Templates</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>value</td>
                            <td>$implicit: Value of the component <br />
                                placeholder: Placeholder text to show</td>
                        </tr>
                        <tr>
                            <td>option</td>
                            <td>$implicit: Data of the option</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Styling</h5>
            <p>Following is the list of structural style classes, for theming classes visit <a href="#" [routerLink]="['/theming']">theming</a> page.</p>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Element</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>p-cascadeselect</td>
                            <td>Container element.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-label</td>
                            <td>Element to display label of selected option.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-trigger</td>
                            <td>Icon element.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-panel</td>
                            <td>Icon element.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-items-wrapper</td>
                            <td>Wrapper element of items list.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-items</td>
                            <td>List element of items.</td>
                        </tr>
                        <tr>
                            <td>p-cascadeselect-item</td>
                            <td>An item in the list.</td>
                        </tr>
                    </tbody>
                </table>
            </div>
                
            <h5>Dependencies</h5>
            <p>None.</p>
        </p-tabPanel>

        <p-tabPanel header="Source">
            <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/cascadeselect" class="btn-viewsource" target="_blank">
                <span>View on GitHub</span>
            </a>
            <a href="https://stackblitz.com/edit/primeng-cascadeselect-demo" class="btn-viewsource" style="margin-left: .5em;" target="_blank">
                <span>Edit in StackBlitz</span>
            </a>
            
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;h5&gt;Basic&lt;/h5&gt;
&lt;p-cascadeSelect [(ngModel)]="selectedCity1" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
    [optionGroupChildren]="['states', 'cities']" [style]="&#123;'minWidth': '14rem'&#125;" placeholder="Select a City"&gt;&lt;/p-cascadeSelect&gt;
    
&lt;h5&gt;Templating&lt;/h5&gt;
&lt;p-cascadeSelect [(ngModel)]="selectedCity2" [options]="countries" optionLabel="cname" optionGroupLabel="name" 
    [optionGroupChildren]="['states', 'cities']" [style]="&#123;'minWidth': '14rem'&#125;" placeholder="Select a City"&gt;
    &lt;ng-template pTemplate="option" let-option&gt;
        &lt;div class="country-item"&gt;
            &lt;img *ngIf="option.states" src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + option.code.toLowerCase()"/&gt;
            &lt;i class="pi pi-compass mr-2" *ngIf="option.cities"&gt;&lt;/i&gt;
            &lt;i class="pi pi-map-marker mr-2" *ngIf="option.cname"&gt;&lt;/i&gt;
            &lt;span&gt;&#123;&#123;option.cname || option.name&#125;&#125;&lt;/span&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-cascadeSelect&gt;
</app-code>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class CascadeSelectDemo &#123;

    countries: any[];

    selectedCity1: any;

    selectedCity2: any;

    ngOnInit() &#123;
        this.countries = [
            &#123;
                name: 'Australia',
                code: 'AU',
                states: [
                    &#123;
                        name: 'New South Wales',
                        cities: [
                            &#123;cname: 'Sydney', code: 'A-SY'&#125;,
                            &#123;cname: 'Newcastle', code: 'A-NE'&#125;,
                            &#123;cname: 'Wollongong', code: 'A-WO'&#125;
                        ]
                    &#125;,
                    &#123;
                        name: 'Queensland',
                        cities: [
                            &#123;cname: 'Brisbane', code: 'A-BR'&#125;,
                            &#123;cname: 'Townsville', code: 'A-TO'&#125;
                        ]
                    &#125;,
                    
                ]
            &#125;,
            &#123;
                name: 'Canada', 
                code: 'CA',
                states: [
                    &#123;
                        name: 'Quebec',
                        cities: [
                            &#123;cname: 'Montreal', code: 'C-MO'&#125;,
                            &#123;cname: 'Quebec City', code: 'C-QU'&#125;
                        ]
                    &#125;,
                    &#123;
                        name: 'Ontario',
                        cities: [
                            &#123;cname: 'Ottawa', code: 'C-OT'&#125;,
                            &#123;cname: 'Toronto', code: 'C-TO'&#125;
                        ]
                    &#125;,
                    
                ]
            &#125;,
            &#123;
                name: 'United States',
                code: 'US',
                states: [
                    &#123;
                        name: 'California',
                        cities: [
                            &#123;cname: 'Los Angeles', code: 'US-LA'&#125;,
                            &#123;cname: 'San Diego', code: 'US-SD'&#125;,
                            &#123;cname: 'San Francisco', code: 'US-SF'&#125;
                        ]
                    &#125;,
                    &#123;
                        name: 'Florida',
                        cities: [
                            &#123;cname: 'Jacksonville', code: 'US-JA'&#125;,
                            &#123;cname: 'Miami', code: 'US-MI'&#125;,
                            &#123;cname: 'Tampa', code: 'US-TA'&#125;,
                            &#123;cname: 'Orlando', code: 'US-OR'&#125;
                        ]
                    &#125;,
                    &#123;
                        name: 'Texas',
                        cities: [
                            &#123;cname: 'Austin', code: 'US-AU'&#125;,
                            &#123;cname: 'Dallas', code: 'US-DA'&#125;,
                            &#123;cname: 'Houston', code: 'US-HO'&#125;
                        ]
                    &#125;
                ]
            &#125;
        ];
    &#125;
&#125;
</app-code>
        </p-tabPanel>
        <p-tabPanel header="StackBlitz">
            <ng-template pTemplate="content">
                <iframe src="https://stackblitz.com/edit/primeng-cascadeselect-demo?embed=1" style="width: 100%; height: 768px; border: none;"></iframe>
            </ng-template>
        </p-tabPanel>
    </p-tabView>
</div>